package org.sosie2.service.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.message.MessageElement;
import org.apache.axis.message.PrefixedQName;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.opensaml.SAMLAttribute;
import org.opensaml.SAMLException;
import org.sosie2.service.framework.AbstractService;
import org.sosie2.service.framework.SAMLAnnotation;
import org.sosie2.service.framework.SosieException;
import org.sosie2.service.framework.Utils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * This is a dummy service used for testing the framework. It adds a SOAPBodyElement to the initial message.
 * 
 * @author Gabriela
 * @author oppy
 */

public class DummyService extends AbstractService {
	
	public static Logger logger = Logger.getLogger(DummyService.class); 
	
	public String textToAdd = this.getClass().getSimpleName(); 
	
	
	/**
	 * The initialization of the logger attached to this service
	 */
	public void init() {
		Utils instanceUtils = Utils.get();
		URL url = instanceUtils.getFile("configuration//" + Utils.LOGGER_FILE);
		if (url == null)
			logger.info("URL is NULL" );
		else {	
			PropertyConfigurator.configure(url);
		}
		org.apache.xml.security.Init.init();
	}	
	
	
	/**
	 *  A simple constructor that calls init()
	 */
	public DummyService() {
		init();
	}
	
	
	public Message invoke(Message req, Message resp) throws Exception {
		logger.info("begin");
		logger.info("Request: " + req.getSOAPBody().toString());
				
		// Copy Header
		SOAPHeader header = req.getSOAPHeader();
		copyHeader(header, resp.getSOAPHeader());
		
		// Copy Body
		copyBody(req.getSOAPBody(), resp.getSOAPBody());
		
		// Add a tag to the body				
		SOAPBody respBody = resp.getSOAPBody();
		SOAPBodyElement e = respBody.addBodyElement(new PrefixedQName("http://unibw.de/sosie", textToAdd, "sosie"));				
		e.addTextNode("Timestamp: " + (new Date()));
		
		Document doc = resp.getSOAPEnvelope().getAsDocument();
		SOAPMessage soapMsg = Utils.toMessage(doc);
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		soapMsg.writeTo(out);

		//set the response message 
		Message msg = new Message(new ByteArrayInputStream(out.toByteArray()), false);
	    logger.info("finished");	  
	    
	    return msg;
    }
    	
	
	/**
	 * This function iterates recursively over a node list. 
	 * It is searching for a specific tag, and returns the value into a class property - textToAdd in this case
	 * 
	 * @param nl - the node list of the message body being examined
	 * @param nameTag - the tag that is searched
	 */	
	 public void iterateNodes(NodeList nl, String nameTag) {
		//iterate through child elements
		for(int i = 0; i < nl.getLength() && this.textToAdd == null; i++) {
		    Node node = nl.item(i);
		    // get the soap element
		    if (node instanceof SOAPElement) {
		    	SOAPElement se = (SOAPElement)node;
		    	// get the name of operation being performed
		   		String operationName = se.getLocalName();
		  		// if operation is to create new account
		   		if(operationName.equals(nameTag)) {
		   			this.textToAdd =  new String((String)node.getFirstChild().getNodeValue());
		   			logger.info("Found the tag..." + textToAdd);			   			
		   			return;
		   		} else {
		   			NodeList newnl = node.getChildNodes();
		   			iterateNodes(newnl, nameTag);
		   		}
		    }
		} 
	} 	 
}